Permutation<U>
Union型を、順列の配列に変換
type-challenges 296
これで中級なん!?になったmrsekut.icon
練習としてやるなら先にIsUnion<T>をやってみるといい
似た知識が必要でIsUnionの方が簡単
Combination<U>もほしくなるなmrsekut.icon
使用例
code:ts
type Perm = Permutation<'A' | 'B' | 'C'>;
/**
* 'A', 'B', 'C'
* | 'A', 'C', 'B'
* | 'B', 'A', 'C'
* | 'B', 'C', 'A'
* | 'C', 'A', 'B'
* | 'C', 'B', 'A'
*/
定義
code:ts
type Permutation<T, U = T> =
T extends never ? []
: T extends T ? T, ...Permutation<Exclude<U, T>>
: never;
[T] extends [never]
単純に、Tがneverかどうか?の条件分岐を書きたい
しかし、単純にT extends neverとは書けない
ref T がneverの時の、T extends .. は、問答無用でneverになる
そこで、[U] extends ..でdistributeを避けるを使ってtupleにしている
T extends T
UnionからUnionへの型レベルmap
T extends T ? [..]の形なので、「配列のunion」にしている
型引数U
「分配前のT」を保存するために型引数Uを定義している
分配されてT=1の時に着目すると、
T extends Tの?節は、[1, ...Permutaion<2|3>]になる
Permutation<2|3>は、[2,3]|[3,2]なので、
結果として[1,2,3]|[1,3,2]になる
ref tuple内のunion distribution
考え方
まず大枠を見れば、(文字の)Union→(配列の)Unionの変換であることから
UnionからUnionへの型レベルmapが使えると推測できる
すると、distributeされるので、例えばT=1の時に着眼できる
後は、tail(2|3)と再帰を使っていい感じにやろう〜ってことか
難し〜〜mrsekut.icon
U=TとExcludeを使ったUnion tailのパターンは他でも応用が効くような気もするmrsekut.icon
一応リンクしておくmrsekut.icon
参考
296 - Permutation (with explanations) · Issue #614 · type-challenges/type-challenges
詳しい解説
ぐぐったら引数が配列のやつも出てきた
https://susisu.hatenablog.com/entry/2020/03/04/230120
https://susisu.hatenablog.com/entry/2020/01/30/015224
https://gist.github.com/dfoverdx/8a044df48f6fa71a75caa2e6c56bd5b0
多分古いのでもうちょい簡潔に書ける